package com.xuecheng.media.service.impl;

import com.alibaba.cloud.commons.lang.StringUtils;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.vod.model.v20170321.GetPlayInfoResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xuecheng.api.content.model.dto.CourseBaseDTO;
import com.xuecheng.api.media.model.dto.MediaDTO;
import com.xuecheng.api.media.model.qo.QueryMediaModel;
import com.xuecheng.common.constant.ContentErrorCode;
import com.xuecheng.common.domain.code.CommonErrorCode;
import com.xuecheng.common.domain.page.PageRequestParams;
import com.xuecheng.common.domain.page.PageVO;
import com.xuecheng.common.domain.response.RestResponse;
import com.xuecheng.common.enums.common.AuditEnum;
import com.xuecheng.common.enums.common.CommonEnum;
import com.xuecheng.common.enums.content.CourseAuditEnum;
import com.xuecheng.common.exception.ExceptionCast;
import com.xuecheng.common.util.StringUtil;
import com.xuecheng.media.common.constant.MediaErrorCode;
import com.xuecheng.media.common.utils.AliyunVODUtil;
import com.xuecheng.media.controller.MediaController;
import com.xuecheng.media.convert.MediaConvert;
import com.xuecheng.media.entity.Media;
import com.xuecheng.media.mapper.MediaMapper;
import com.xuecheng.media.service.MediaService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;

/**
 * <p>
 * 媒资信息 服务实现类
 * </p>
 *
 * @author itcast
 */
@Slf4j
@Service
public class MediaServiceImpl extends ServiceImpl<MediaMapper, Media> implements MediaService {


    String region = "cn-shanghai";
    String accessKeyId = "LTAI5t83PEYGZKWFsA3F1W8Y";
    String accessKeySecret = "EZw9u7lIPy2B6nABWJE8JAeoqdUkZw";


    /*
     * 业务分析：
     *   1.判断关键
     *       companyid  filename  fileid(videoId)
     *   2.给信息数据赋值默认值
     *       auditStatus：未审核
     *
     *   3.保存信息
     *   4.将数据库最新数据返回
     *
     * */
    @Transactional
    public MediaDTO createMedia(MediaDTO dto) {

        //1.判断关键
        //     *       companyid  filename  fileid(videoId)
        if (ObjectUtils.isEmpty(dto.getCompanyId())||
                StringUtil.isBlank(dto.getFilename())||
                StringUtil.isBlank(dto.getFileId())
        ){
            ExceptionCast.cast(ContentErrorCode.E_120025);
        }

        //2.给信息数据赋值默认值
        //    auditStatus：未审核
        dto.setAuditStatus(AuditEnum.AUDIT_UNPAST_STATUS.getCode());

        //        3.保存信息
        Media media = MediaConvert.INSTANCE.dto2entity(dto);
        boolean save = this.save(media);
        if (!save) {
            ExceptionCast.cast(MediaErrorCode.E_140001);
        }

        //4.将数据库最新数据返回
        Media po = this.getById(media.getId());
        MediaDTO mediaDTO = MediaConvert.INSTANCE.entity2dto(po);

        return mediaDTO;
    }

    @Override
    public PageVO queryMediaBaseList(PageRequestParams params, QueryMediaModel model, Long companyId) {

        // 1.判断关键数据
        // 分页数据的合法性
        if (params.getPageNo() < 1) {
            params.setPageNo(PageRequestParams.DEFAULT_PAGE_NUM);
        }

        if (params.getPageSize() < 1) {
            params.setPageSize(PageRequestParams.DEFAULT_PAGE_SIZE);
        }


        // 2.构建分页对象
        Page<Media> basePage = new Page<>(params.getPageNo(),params.getPageSize());

        // 3.构建查询条件对象
        LambdaQueryWrapper<Media> queryWrapper = new LambdaQueryWrapper<>();

        // 课程名称     like   完整版
        // 课程审核状态  eq

        queryWrapper.like(StringUtil.isNotBlank(model.getFilename()),Media::getFilename, model.getFilename());
        queryWrapper.eq(StringUtil.isNotBlank(model.getType()),Media::getType, model.getType());
//        queryWrapper.eq(StringUtils.isNotBlank(model.getAuditStatus()),
//                Media::getAuditStatus, model.getAuditStatus());


        if (!(ObjectUtils.nullSafeEquals(companyId, MediaController.OPERATION_FLAG))) {
            queryWrapper.eq(Media::getCompanyId, companyId);
        }




        // 4.查询数据内容获得结果
        Page<Media> page = this.page(basePage, queryWrapper);

        List<Media> records = page.getRecords();
        long total = page.getTotal();


        List<MediaDTO> dtos = Collections.emptyList();

        if (!(CollectionUtils.isEmpty(records))) {
            dtos = MediaConvert.INSTANCE.entitys2dtos(records);
        }

        // 5.构建返回结果数据-PageVo
        PageVO pageVO = new PageVO(dtos,total,params.getPageNo(),params.getPageSize());

        return pageVO;
    }

    //业务分析：

    //1.判断关键数据
    //	mediaId、companyId
    //	2.判断业务数据
    //	媒资信息
    //		判断是否存在
    //			判断审核状态：只有审核通过不能删除
    //		判断媒资信息是否有绑定课程计划数据
    //			绑定媒资和课程计划数据：content（发送feign）
    //				 teachplan_media
    //3.删除媒资信息
    //		媒资服务中的数据：Media
    //	阿里云对应的视频
    public void removeMediaId(Long maediaId,Long companyId) {
        //1.判断关键数据
        //	mediaId、companyId
        if (ObjectUtils.isEmpty(maediaId)||
                ObjectUtils.isEmpty(companyId)
        ) {
            ExceptionCast.cast(ContentErrorCode.E_120406);
        }
        //	2.判断业务数据
        //	媒资信息
        //		判断是否存在
        //			判断审核状态：只有审核通过不能删除
        //		判断媒资信息是否有绑定课程计划数据
        //			绑定媒资和课程计划数据：content（发送feign）
        //				 teachplan_media


    }


    public void commitMedia(MediaDTO dto) {

        //判断关键数据
        if (StringUtil.isBlank(dto.getAuditMind())||
                StringUtil.isBlank(dto.getAuditStatus()) ||
                ObjectUtils.isEmpty(dto.getId())
        ) {
            ExceptionCast.cast(ContentErrorCode.E_120022);
        }

        //2.判断业务数据
        //        课程基础信息
        //判断是否存在
        //        判断是否删除
        //判断审核状态
        //必须为：已提交
        //        审核状态
        //运营平台只能给课程审核状态赋值：审核通过、审核未通过
        LambdaQueryWrapper<Media> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Media::getId, dto.getId());
        queryWrapper.eq(Media::getStatus, CommonEnum.USING_FLAG.getCodeInt());
        queryWrapper.eq(Media::getAuditStatus, CourseAuditEnum.AUDIT_UNPAST_STATUS.getCode());

        int count = this.count(queryWrapper);

        if (count < 1) {
            ExceptionCast.cast(ContentErrorCode.E_120023);
        }

        //      审核状态
        //          运营平台只能给课程审核状态赋值：审核通过、审核未通过
        String auditStatus = dto.getAuditStatus();
        if (CourseAuditEnum.AUDIT_PUBLISHED_STATUS.getCode().equals(auditStatus)||
                CourseAuditEnum.AUDIT_UNPAST_STATUS.getCode().equals(auditStatus)
        ) {
            ExceptionCast.cast(ContentErrorCode.E_120016);
        }

        //  3.修改课程审核信息
        //      auditMind  auditStatus  auditNum（每次+1）

        LambdaUpdateWrapper<Media> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(Media::getAuditStatus, CourseAuditEnum.AUDIT_PASTED_STATUS.getCode());
        updateWrapper.set(Media::getAuditMind, dto.getAuditMind());
        // 使用redis来实现
        // updateWrapper.set(CourseBase::getAuditNums, dto.getAuditMind());
        updateWrapper.set(Media::getChangeDate, LocalDateTime.now());
        updateWrapper.eq(Media::getId, dto.getId());

        boolean result = this.update(updateWrapper);

        if (!result) {
            ExceptionCast.cast(ContentErrorCode.E_120017);
        }


    }

    @Override
    public String previewMedia(Long mediaId,Long companyId) {
        // 1.判断业务数据
        if (ObjectUtils.isEmpty(mediaId)) {
            ExceptionCast.cast(CommonErrorCode.E_100101);
        }
        // 2.根据媒资id获得媒资信息
        Media media = getById(mediaId);
        if (ObjectUtils.isEmpty(media)) {
            ExceptionCast.cast(CommonErrorCode.E_100104);
        }

        if (!(ObjectUtils.nullSafeEquals(companyId, MediaController.OPERATION_FLAG))) {
            // 3.如果公司id不为空，对其进行判断
            if (!(ObjectUtils.isEmpty(companyId))) {
                if (!(ObjectUtils.nullSafeEquals(media.getCompanyId(), companyId))) {
                    ExceptionCast.cast(CommonErrorCode.E_100108);
                }
            }
        }


        String playUrl = getPlayUrl(media.getFileId());


        // 4.返回媒资的资源地址
        return playUrl;
    }


    private String getPlayUrl(String videoId) {

        String playUrl = "";
        try {

            DefaultAcsClient client =
                    AliyunVODUtil.initVodClient(region,accessKeyId,accessKeySecret);

            GetPlayInfoResponse response = AliyunVODUtil.getPlayInfo(client,videoId);

            List<GetPlayInfoResponse.PlayInfo> playInfoList = response.getPlayInfoList();

            if (!(ObjectUtils.isEmpty(playInfoList))) {
                GetPlayInfoResponse.PlayInfo playInfo = playInfoList.get(0);
                playUrl = playInfo.getPlayURL();
            }

        } catch (Exception e) {
            ExceptionCast.cast(MediaErrorCode.E_140014);
        }
        return playUrl;
    }

    /*
     * 业务分析：
     *   PS：由于是学成内部微服务间的调用，此功能只需要提供基础数据即可，不需要加上业务逻辑判断
     *   如果为了数据的完整性，可以对传入和传出的参数进行判断
     *
     *   1.判断mediaid是否为空
     *   2.查询数据
     *   3.判断数据是否存在
     *   4.如果存在，使用RestResponse来封装返回
     * */
    public RestResponse<MediaDTO> getMedia4Service(Long mediaId) {
        //1.判断mediaid是否为空
        if (ObjectUtils.isEmpty(mediaId)) {
            return RestResponse.validfail(CommonErrorCode.E_100101);
        }

        //2.查询数据
        Media media = this.getById(mediaId);
        if (ObjectUtils.isEmpty(media)) {
            return RestResponse.validfail(CommonErrorCode.E_100105);
        }else {

            MediaDTO mediaDTO = MediaConvert.INSTANCE.entity2dto(media);
            return RestResponse.success(mediaDTO);
        }

    }
}
